package org.dtrd.modules.flup.controller;


import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.dtrd.base.BaseController;
import org.dtrd.common.api.vo.Result;
import org.dtrd.common.util.DateUtils;
import org.dtrd.config.system.Constant;
import org.dtrd.modules.base.service.BaseCommonService;
import org.dtrd.modules.flup.entity.bean.*;
import org.dtrd.modules.flup.entity.po.DtrdEntRdFlupAppointmentRecord;
import org.dtrd.modules.flup.entity.request.FlupAppointmentRecordListRequest;
import org.dtrd.modules.flup.entity.request.FlupFlowRequest;
import org.dtrd.modules.flup.service.IDtrdEntRdFlupAppointmentRecordService;
import org.dtrd.modules.flup.service.IDtrdEntRdFlupEvaluationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;

import static org.dtrd.common.constant.CommonConstant.*;
import static org.dtrd.config.system.SystemState.ResponseState.*;

/**
 * <p>
 * 复诊预约记录 前端控制器
 * </p>
 * @author QR
 * @since 2021-12-16
 */
@Api(tags = "复诊随访记录")
@RestController
@RequestMapping("/flup/")
@Slf4j
public class FlupController extends BaseController {

    @Autowired
    private IDtrdEntRdFlupAppointmentRecordService flupAppointmentRecordService;
    @Autowired
    private BaseCommonService baseCommonService;
    @Autowired
    private IDtrdEntRdFlupEvaluationService flupEvaluationService;

    @ApiOperation(value = "查询复诊预约记录详情", response = FlupAppointmentRecordDetail.class)
    @GetMapping("get")
    public Result<?> getFlupAppointmentRecord(@RequestParam Integer id){
        FlupAppointmentRecordDetail info = flupAppointmentRecordService.getFlupAppointmentRecord(id);
        String logContent = String.format("查询复诊预约记录详情，查询id：%d", id);
        baseCommonService.addLog(logContent, OPERATE_TYPE_QUERY);
        return Result.OK(info);
    }

    @ApiOperation(value = "查询复诊预约记录列表", response = DoctorFlupDaily.class, notes = "h5端")
    @PostMapping("list")
    public Result<?> getFlupAppointmentRecordList(@RequestBody FlupAppointmentRecordListRequest request){
        // doctorId 和 查询的日期不能为空
        Integer doctorId = request.getDoctorId();
        String queryDate = request.getQueryDate();
        if (isIntParamInvalid(doctorId) || StrUtil.isBlank(queryDate)) {
            return error(STATE_PARAMS_MISSING);
        }
        // 校验日期格式
        Date startDate;
        try {
            startDate = DateUtils.parseDate(queryDate, DateUtils.short_date_sdf_yd.get().toPattern());
        } catch (ParseException e) {
            log.error("getFlupAppointmentRecordList 请求参数: queryDate, 格式错误: {}", queryDate);
            e.printStackTrace();
            return error(STATE_PARAMS_ERROR);
        }
        List<DoctorFlupDaily> list = flupAppointmentRecordService.getFlupAppointmentRecordList(request, startDate);
        String logContent = String.format("查询复诊预约记录列表, 查询医生Id: %d, 查询日期: %s", request.getDoctorId(), queryDate);
        baseCommonService.addLog(logContent, OPERATE_TYPE_QUERY);
        return Result.OK(list);
    }

    @ApiOperation(value = "查询医生某日的门诊记录", response = DoctorFlupDaily.class)
    @GetMapping("date/get")
    public Result<?> getDoctorFlupRecord(@RequestParam Integer doctorId,
                                         @RequestParam String date){
        if (isIntParamInvalid(doctorId)) {
            return error(STATE_PARAMS_MISSING);
        }
        // 转换日期格式
        Date queryDate;
        try {
            queryDate = DateUtils.parseDate(date, DateUtils.date_sdf.get().toPattern());
        } catch (ParseException e) {
            log.error("getDoctorFlupRecord 请求参数： date, 格式错误{}", date);
            e.printStackTrace();
            return error(STATE_PARAMS_ERROR);
        }
        DoctorFlupDaily doctorFlupDaily = flupAppointmentRecordService.getDoctorFlupByDate(doctorId, queryDate);
        return doctorFlupDaily == null ? error(STATE_NO_RECORD) : Result.OK(doctorFlupDaily);
    }

    @ApiOperation(value = "获取复诊流程",notes = "根据复诊预约记录id获取复诊流程", response = FlupFlowItem.class)
    @GetMapping("flow")
    public Result<?> getFlupFLow(
            @ApiParam(value = "复诊记录id",example = "1", required = true) @RequestParam Integer flupId
    ){
        FlupBasicInfo flupBasicInfo = flupAppointmentRecordService.getFlupInfo(flupId);
        List<FlupFlowItem> flupFlowItems = flupAppointmentRecordService.getFlupFlow(flupId);
        FlupEvaluation flupEvaluation = flupEvaluationService.getFlupEvaluation(flupId);
        DtrdEntRdFlupAppointmentRecord flupRecord = flupAppointmentRecordService.getById(flupId);
        JSONObject result = new JSONObject();
        result.put("flupId", flupId);
        result.put("flupBasicInfo", flupBasicInfo);
        result.put("flupFLowItems", flupFlowItems);
        result.put("flupEvaluation", flupEvaluation);
        result.put("flupStatus", Optional.ofNullable(flupRecord)
                .map(DtrdEntRdFlupAppointmentRecord::getFlupStatus)
                .orElse(Constant.FlupStatus.NoAppointment.getStatus()));
        // 记录日志
        String logContent = String.format("获取复诊流程, 复诊记录id: %d", flupId);
        baseCommonService.addLog(logContent, OPERATE_TYPE_QUERY);
        return Result.OK(result);
    }

    @ApiOperation(value = "保存复诊流程内容")
    @PostMapping("flow/save")
    public Result<?> saveFlupFlow(@RequestBody FlupFlowRequest request){
        Integer flupId = request.getFlupId();
        List<FlupFlowItem> flupFlowItems = request.getFlupFlowItems();
        if (isIntParamInvalid(flupId)) {
            return error(STATE_PARAMS_MISSING);
        }
        // 如果项目数据内容为空则直接返回成功
        if (CollectionUtil.isEmpty(flupFlowItems)) {
            return Result.OK();
        }
        boolean result = flupAppointmentRecordService.saveFlupFlow(flupFlowItems, flupId);
        String logContent = String.format("保存复诊流程内容, 保存流程内容Id: %s", flupFlowItems);
        baseCommonService.addLog(logContent, OPERATE_TYPE_ADD);
        return result ? Result.OK() : error(STATE_OPERATION_FAILURE);
    }

    @ApiOperation("删除复诊预约记录")
    @DeleteMapping("remove")
    public Result<?> removeFlupAppointmentRecord(@RequestParam Integer id){
        if(isIntParamInvalid(id)) {
            return error(STATE_PARAMS_MISSING);
        }
        boolean result = flupAppointmentRecordService.removeFlupAppointmentRecord(id);
        String logContent = String.format("删除复诊预约记录, 删除复诊预约记录id: %d", id);
        baseCommonService.addLog(logContent, OPERATE_TYPE_DELETE);
        return result ? Result.OK() : error(STATE_OPERATION_FAILURE);
    }

    @ApiOperation("获取复诊预约时间段列表")
    @GetMapping("time")
    public Result<?> listFlupTime() {
        Constant.FlupTime[] values = Constant.FlupTime.values();
        HashMap<Integer, String> map = new HashMap<>(values.length);
        for (Constant.FlupTime value : values) {
            int type = value.getType();
            if (type != 0) {
                String flupTime = value.getStartTime() + " ~ " +value.getEndTime();
                map.put(type, flupTime);
            }
        }
        return Result.OK(map);
    }
}
